]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
st: Track stylesheet changes on the StThemeContext
authorCarlos Garnacho <carlosg@gnome.org>
Thu, 24 Oct 2019 12:03:12 +0000 (14:03 +0200)
committerFlorian Müllner <florian.muellner@gmail.com>
Tue, 5 Nov 2019 12:36:28 +0000 (12:36 +0000)
Instead of every individual StThemeNode. There are essentially two kinds
of theme nodes: Those we create for lookups, and those interned by the
theme context and used by StWidgets. Listening to the signal on the former
is pointless as they are short lived and not meant to be really used for
drawing. So it is only essential to track stylesheet changes in those we
intern for later use.

This change does precisely that, it lets the StThemeContext track the
stylesheet changes and let all known theme nodes reset their state for
it.

The internal array holding all connected handlers for this signal in glib
was about the biggest single allocation made in gnome-shell, as interned
theme nodes nodes are around the 4 to 5 digit numbers. This essentially
makes it disappear.

This however means that widgets that are explicitly set a theme through
st_widget_set_theme() don't get their theme node implicitly updated.
There's little reasons to use that API, so perhaps this is an acceptable
tradeoff.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/779

src/st/st-theme-context.c
src/st/st-theme-node-private.h
src/st/st-theme-node.c

index 1087dfe7d730f6807e6f848abee156878e4c5eb8..7b1b03a45bb1d075430024f1439b8be20d41c5c3 100644 (file)
@@ -25,6 +25,7 @@
 #include "st-texture-cache.h"
 #include "st-theme.h"
 #include "st-theme-context.h"
+#include "st-theme-node-private.h"
 
 struct _StThemeContext {
   GObject parent;
@@ -36,6 +37,8 @@ struct _StThemeContext {
   /* set of StThemeNode */
   GHashTable *nodes;
 
+  gulong stylesheets_changed_id;
+
   int scale_factor;
 };
 
@@ -83,6 +86,8 @@ st_theme_context_finalize (GObject *object)
                                         (gpointer) st_theme_context_changed,
                                         context);
 
+  g_clear_signal_handler (&context->stylesheets_changed_id, context->theme);
+
   if (context->nodes)
     g_hash_table_unref (context->nodes);
   if (context->root_node)
@@ -254,6 +259,19 @@ on_icon_theme_changed (StTextureCache *cache,
   g_source_set_name_by_id (id, "[gnome-shell] changed_idle");
 }
 
+static void
+on_custom_stylesheets_changed (StTheme        *theme,
+                               StThemeContext *context)
+{
+  GHashTableIter iter;
+  StThemeNode *node;
+
+  g_hash_table_iter_init (&iter, context->nodes);
+
+  while (g_hash_table_iter_next (&iter, (gpointer *) &node, NULL))
+    _st_theme_node_reset_for_stylesheet_change (node);
+}
+
 /**
  * st_theme_context_get_for_stage:
  * @stage: a #ClutterStage
@@ -299,12 +317,17 @@ st_theme_context_set_theme (StThemeContext          *context,
   if (context->theme != theme)
     {
       if (context->theme)
-        g_object_unref (context->theme);
+        g_clear_signal_handler (&context->stylesheets_changed_id, context->theme);
 
-      context->theme = theme;
+      g_set_object (&context->theme, theme);
 
       if (context->theme)
-        g_object_ref (context->theme);
+        {
+          context->stylesheets_changed_id =
+            g_signal_connect (context->theme, "custom-stylesheets-changed",
+                              G_CALLBACK (on_custom_stylesheets_changed),
+                              context);
+        }
 
       st_theme_context_changed (context);
     }
index 47be65dba83aa3d435895c0aaf682e8ac96e191f..578a06e72b6d9bff75df18981427da1da2ef3e5f 100644 (file)
@@ -123,6 +123,7 @@ void _st_theme_node_ensure_background (StThemeNode *node);
 void _st_theme_node_ensure_geometry (StThemeNode *node);
 void _st_theme_node_apply_margins (StThemeNode *node,
                                    ClutterActor *actor);
+void _st_theme_node_reset_for_stylesheet_change (StThemeNode *node);
 
 G_END_DECLS
 
index 1261e92573d2d08878eaf3d7e5452565505c135e..2454fd0aa4ec561ddc7c5a8bfebc7338189f74b3 100644 (file)
@@ -77,16 +77,13 @@ maybe_free_properties (StThemeNode *node)
     }
 }
 
-static void
-on_custom_stylesheets_changed (StTheme *theme,
-                               gpointer data)
+void
+_st_theme_node_reset_for_stylesheet_change (StThemeNode *node)
 {
-  StThemeNode *node = data;
   maybe_free_properties (node);
   node->properties_computed = FALSE;
 }
 
-
 static void
 st_theme_node_dispose (GObject *gobject)
 {
@@ -110,12 +107,6 @@ st_theme_node_dispose (GObject *gobject)
       node->icon_colors = NULL;
     }
 
-  if (node->theme && node->stylesheets_changed_id)
-    {
-      g_signal_handler_disconnect (node->theme, node->stylesheets_changed_id);
-      node->stylesheets_changed_id = 0;
-    }
-
   st_theme_node_paint_state_free (&node->cached_state);
 
   g_clear_object (&node->theme);
@@ -228,14 +219,7 @@ st_theme_node_new (StThemeContext    *context,
   if (theme == NULL && parent_node != NULL)
     theme = parent_node->theme;
 
-  if (theme != NULL)
-    {
-      node->theme = g_object_ref (theme);
-      node->stylesheets_changed_id =
-        g_signal_connect (node->theme, "custom-stylesheets-changed",
-                          G_CALLBACK (on_custom_stylesheets_changed), node);
-    }
-
+  g_set_object (&node->theme, theme);
   node->element_type = element_type;
   node->element_id = g_strdup (element_id);
   node->element_classes = split_on_whitespace (element_class);